package showtime.framework.component.loading
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	import flash.utils.ByteArray;
	
	public class GroupLoader extends EventDispatcher
	{	
		private var index:int = 0;
	
		private var queue:Array = null;
	
		private var bmpCache:Object = null;

		private var xmlCache:Object = null;
		
		private var swfCache:Object = null;
		
		private var binaryCache:Object = null;
		
		private var lastAccessURL:String = null;

		public function GroupLoader()
		{
			super(this);
			
			queue = [];

			bmpCache = {};

			xmlCache = {};
			
			binaryCache = {};
			
			swfCache = {};
		}
		
		/**
		 * 添加加载文件的URL。
		 *  
		 * @param url
		 * 
		 */		
		public function addURL(url:String):void
		{
			index++;
			queue.push(url);
	
		}	
		
		/**
		 * 启动加载。 
		 * 
		 */		
		public function start():void
		{			
			if (queue.length == 0)
			{
				return;
			}
			
			lastAccessURL = queue.shift();
			
			var request:URLRequest = new URLRequest(lastAccessURL);			
			var key:String = request.url.split("/").reverse()[0].split(".")[0];
			
			switch (filePathToFileExt(request.url).toLocaleLowerCase())
			{
				case "swf":
				{
					var swfLoader:Loader = new Loader();
					swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSwfLoadComplete);
					swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
					swfLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIoError);

					if (isHTTP(request.url))
					{
						swfLoader.load(new URLRequest(request.url), new LoaderContext(false, ApplicationDomain.currentDomain, SecurityDomain.currentDomain));
					}
					else
					{
						swfLoader.load(new URLRequest(request.url), new LoaderContext(false, ApplicationDomain.currentDomain));	
					}

					break;
					
				} 
				case "jpg":
				case "png":
				case "gif":
				{
					var bmpLoader:Loader = new Loader();					
					bmpLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBmpLoadComplete);
					bmpLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
					bmpLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIoError);					
					bmpLoader.load(new URLRequest(request.url));
					break;
				}

				// 加载XML。
				case "tmx":
				case "xml":
				{	
					var xmlLoader:URLLoader = new URLLoader();
					xmlLoader.dataFormat = URLLoaderDataFormat.TEXT;
					xmlLoader.addEventListener( Event.COMPLETE, onXmlLoadComplete );
					xmlLoader.addEventListener(ProgressEvent.PROGRESS, onProgress);
					xmlLoader.addEventListener( IOErrorEvent.IO_ERROR, onIoError );
					xmlLoader.load(new URLRequest(request.url));
					break;
				}
				case "zip":
				{
					var binaryLoader:URLLoader = new URLLoader();
					binaryLoader.dataFormat = URLLoaderDataFormat.BINARY;
					binaryLoader.addEventListener(Event.COMPLETE, onBinaryLoadComplete);
					binaryLoader.addEventListener(ProgressEvent.PROGRESS, onProgress);
					binaryLoader.addEventListener( IOErrorEvent.IO_ERROR, onIoError );
					binaryLoader.load(new URLRequest(request.url));
					break;
				}
					
			}
			
			function onBinaryLoadComplete(event:Event):void
			{
				event.target.removeEventListener(Event.COMPLETE, onBinaryLoadComplete);	
				event.target.removeEventListener(IOErrorEvent.IO_ERROR, onIoError);	
				event.target.removeEventListener(ProgressEvent.PROGRESS, onProgress);
				binaryCache[key] = event.target.data;
				
				next();
			}

			function onBmpLoadComplete(event:Event):void
			{			
				bmpCache[key] = Bitmap(event.target.content).bitmapData;				
				event.target.removeEventListener(Event.COMPLETE, onBmpLoadComplete);	
				event.target.removeEventListener(IOErrorEvent.IO_ERROR, onIoError);	
				event.target.removeEventListener(ProgressEvent.PROGRESS, onProgress);
				
				next();
	
			}
			
			function onSwfLoadComplete(event:Event):void
			{	
				event.target.removeEventListener(Event.COMPLETE, onSwfLoadComplete);
				event.target.removeEventListener(ProgressEvent.PROGRESS, onProgress);	
				event.target.removeEventListener(IOErrorEvent.IO_ERROR,onIoError);				
				swfCache[key] = event.target.content;
				
				next();
		
			}
			
			function onXmlLoadComplete(event:Event):void
			{
				xmlCache[key] = XML(event.target.data);
				
				event.target.removeEventListener(Event.COMPLETE, onXmlLoadComplete);
				event.target.removeEventListener(ProgressEvent.PROGRESS, onProgress);
				event.target.removeEventListener(IOErrorEvent.IO_ERROR,onIoError);
				
				next();
			}			
			
		}
		
		private function next():void
		{
			if (queue.length > 0)
			{
				start();
			}
			else
			{
				index = 0;
				
				dispatchEvent(new GroupLoaderEvent(GroupLoaderEvent.COMPLETE));
			}
		}

		private function onIoError (event:IOErrorEvent ):void
		{
			event.target.removeEventListener(IOErrorEvent.IO_ERROR,onIoError);
			dispatchEvent(event);
		}
		
		private function onProgress(event:ProgressEvent):void
		{
			dispatchEvent(new GroupLoaderEvent(GroupLoaderEvent.PROGRESS, false, false, event.bytesLoaded, event.bytesTotal, queue.length, index, filePathToFileName(lastAccessURL)));
		}
		
		public function getBMP(key:String):BitmapData
		{
			if (bmpCache.hasOwnProperty(key))
			{
				return bmpCache[key];
			}
			
			return null;
		}
	
		public function getXML(key:String):XML
		{
			if (xmlCache.hasOwnProperty(key))
			{
				return XML(xmlCache[key]);
			}
			
			return null;
		}
		
		public function getBinary(key:String):ByteArray
		{
			return binaryCache.hasOwnProperty(key) ? binaryCache[key] : null; 
		}

		public function unload():void
		{
			bmpCache = null;
			
			xmlCache = null;
			
			binaryCache = null;
			
			swfCache = null;
		}
		
		private function isHTTP(char:String):Boolean
		{
			return char.substr(0,7).toLowerCase() == "http://";
		}
		
		private function filePathToFileExt(path:String):String
		{
			path = path.slice(path.lastIndexOf(".") + 1);
			
			return path;
		}

		private function filePathToFileName(path:String):String
		{
			path = path.slice(path.lastIndexOf("/") + 1);
			path = path.slice(0, path.indexOf("."));
			
			return path;
		}
	}
}